<?php


class AutomateBehavior extends ModelBehavior {

/******************************************************************************/

var $settings = array();

/******************************************************************************/

var $fieldInputSchema = array(
	// general
	'id' => array('type' => 'hidden'),
	'parent_id' => array('empty' => '(root)'),
	'lft' => array('type' => 'skip'),
	'rght' => array('type' => 'skip'),
	'slug' => array(),
	'name' => array(),
	'label' => array(),
	'caption' => array(),
	'brief' => array('type' => 'wysiwyg'),
	'content' => array('type' => 'wysiwyg'),
	'message' => array('type' => 'wysiwyg'),
	'quote' => array('type' => 'wysiwyg'),
	//'biography' => array('type' => 'wysiwyg'),
	'published' => array(),
	'displayed' => array(),
	'position' => array('type' => 'skip'),
	'locked' => array(),
	'hidden' => array(),
	'disabled' => array(),
	'deleted' => array('type' => 'skip'),
	// meta
	//'meta_title' => array('tab' => 'meta'),
	//'meta_subtitle' => array('tab' => 'meta'),
	//'meta_description' => array('tab' => 'meta'),
	//'meta_keywords' => array('tab' => 'meta'),
	//'meta_copyright' => array('tab' => 'meta'),
	//'meta_header_text' => array('tab' => 'meta'),
	//'meta_footer_text' => array('tab' => 'meta'),
	// seo
	//'seo_title' => array('tab' => 'seo'),
	//'seo_subtitle' => array('tab' => 'seo'),
	//'seo_description' => array('tab' => 'seo'),
	//'seo_keywords' => array('tab' => 'seo'),
	//'seo_copyright' => array('tab' => 'seo'),
	//'seo_header_text' => array('tab' => 'seo'),
	//'seo_footer_text' => array('tab' => 'seo'),
	// image
	'image' => array('type' => 'image', 'tab' => 'image', 'params' => 'resize=max&x=1000&y=750'),
	'image_mainpage' => array('type' => 'image', 'tab' => 'image', 'params' => 'source=image&resize=crop&x=320&y=160'),
	'thumbnail' => array('type' => 'image', 'tab' => 'image', 'params' => 'source=image&resize=crop&x=160&y=160'),
	'logo' => array('type' => 'image', 'tab' => 'image'),
	'avatar' => array('type' => 'image', 'tab' => 'image', 'params' => 'resize=crop&x=80&y=80'),
	// picture
	'picture' => array('type' => 'image', 'tab' => 'picture', 'params' => 'resize=max&x=1000&y=750'),
	// photo
	'photo' => array('type' => 'image', 'tab' => 'photo', 'params' => 'resize=crop&x=200&y=300'),
	// file
	'file' => array('type' => 'file', 'tab' => 'file'),
	'document' => array('type' => 'file', 'tab' => 'file'),
	'pricelist' => array('type' => 'file', 'tab' => 'file'),
	// audio
	'audio' => array('type' => 'audio', 'tab' => 'audio'),
	'mp3' => array('type' => 'audio', 'tab' => 'audio'),
	// video
	'video' => array('type' => 'video', 'tab' => 'video'),
	'flv' => array('type' => 'video', 'tab' => 'video'),
	// info
	'note' => array('tab' => 'info'),
	'created' => array('type' => 'static', 'tab' => 'info'),
	'modified' => array('type' => 'static', 'tab' => 'info'),
	// attachment
	'model' => array('type' => 'hidden'),
	'foreign_key' => array('type' => 'hidden'),
	// user
	'username' => array('class' => 'username'),
	'password' => array('type' => 'password', 'class' => 'password'),
	'first_name' => array(),
	'last_name' => array(),
	'email' => array('class' => 'email'),
	'url' => array('class' => 'url')
);

function _describeFieldInput(&$Model, $name, $description = array()) {
	if ($description['input']['type'] === 'skip') return $description['input'];
	switch ($Model->getColumnType($name)) {
		case 'string': {
			$description['input']['type'] = 'text';
			if ($this->isAttachment($Model) && (bool)preg_match('~^model$~', $name)) {
				$description['input']['type'] = 'hidden';
			} elseif ((bool)preg_match('~^(image|thumbnail|logo|avatar)$~', $name)) {
				$description['input']['type'] = 'image';
				$description['input']['tab'] = 'image';
			} elseif ((bool)preg_match('~^(picture|photo|logo)$~', $name, $match)) {
				$description['input']['type'] = 'image';
				$description['input']['tab'] = $match[1];
			} elseif ((bool)preg_match('~^(file|document|pricelist)$~', $name)) {
				$description['input']['type'] = 'file';
				$description['input']['tab'] = 'file';
			} elseif ((bool)preg_match('~^(audio|mp3)$~', $name)) {
				$description['input']['type'] = 'audio';
				$description['input']['tab'] = 'audio';
			} elseif ((bool)preg_match('~^(video|flv)$~', $name)) {
				$description['input']['type'] = 'video';
				$description['input']['tab'] = 'video';
			} elseif ((bool)preg_match('~^password$~', $name)) {
				$description['input']['type'] = 'password';
			}
			// auto class
			if ((bool)preg_match('~^(username|password|email|url)$~', $name, $match)) {
				$description['input']['class'] = $match[1];
			}
			break;
		}
		case 'text': {
			$description['input']['type'] = 'textarea';
			if ((bool)preg_match('~^(brief|content|message|quote)(_[a-z0-9_]+)?$~', $name)) {
				$description['input']['type'] = 'wysiwyg';
			}
			break;
		}
		case 'integer': {
			if ($this->isPrimaryKey($Model, $name)) {
				$description['input']['type'] = 'hidden';
			/*} elseif ($this->isTreeKey($Model, $name)) {
				$description['input']['type'] = 'text';
				$description['input']['class'] = 'integer';
			} elseif ($this->isRubricKey($Model, $name)) {
				$description['input']['type'] = 'text';
				$description['input']['class'] = 'integer';
			} elseif ($this->isForeignKey($Model, $name)) {
				$description['input']['type'] = 'text';
				$description['input']['class'] = 'integer';*/
			} elseif ($this->isAttachment($Model) && (bool)preg_match('~^foreign_key$~', $name)) {
				$description['input']['type'] = 'hidden';
			} else {
				$description['input']['type'] = 'text';
				$description['input']['class'] = 'integer';
			}
			break;
		}
		case 'float': {
			$description['input']['type'] = 'text';
			$description['input']['class'] = 'float';
			break;
		}
		case 'datetime': {
			$description['input']['type'] = 'datetime';
			if ((bool)preg_match('~^(created|modified)$~', $name)) {
				$description['input']['type'] = 'static';
				$description['input']['tab'] = 'info';
			}
			break;
		}
		case 'date': $description['input']['type'] = 'date'; break;
		case 'time': $description['input']['type'] = 'time'; break;
		case 'boolean': $description['input']['type'] = 'checkbox'; break;
		default: $description['input']['type'] = 'text'; break;
	}
	// auto tab
	if ((bool)preg_match('~^(meta|seo|image|picture|photo|logo|file|audio|video|info)(_[a-z0-9_]+)?$~', $name, $match)) {
		$description['input']['tab'] = $match[1];
	}
	return $description['input'];
}

function describeField(&$Model, $name/*, $description = array()*/, $fill = FALSE, $id = NULL, $row = array()) {
	// schema
	//$description = array_merge(array('name' => $name, 'type' => 'string', 'input' => array()), $description);
	$description = array('name' => $name, 'type' => 'string', 'input' => array());
	if ($Model->hasField($name)) $description = array_merge($Model->schema($name), $description);
// label / alias
$msg = $Model->alias . '.' . $name;
$label = __d('x_form', $msg, TRUE);
// label / name
if ($msg == $label) {
	$msg = $Model->name . '.' . $name;
	$label = __d('x_form', $msg, TRUE);
}
// label / Model
if ($msg == $label) {
	$msg = 'Model.' . $name;
	$label = __d('x_form', $msg, TRUE);
}
/////////////
// label / alias
//if ($msg == $label) {
//	$msg = $Model->alias . '.' . $name;
//	$label = __d('x_form', $msg, TRUE);
//}
// label / name
//if ($msg == $label) {
//	$msg = $Model->name . '.' . $name;
//	$label = __d('x_form', $msg, TRUE);
//}
// label / Model
//if ($msg == $label) {
//	$msg = 'Model.' . $name;
//	$label = __d('x_form', $msg, TRUE);
//}

if ($msg == $label) {
	$label = __($name . '_field', TRUE);
	if ((bool)preg_match('~_field$~', $label)) {
		$label = __($name . '_label', TRUE);
	}
	if ((bool)preg_match('~_label$~', $label)) {
		$label = __($name . '_field', TRUE);
	}
}
//
	$description['input'] = array_merge(array('label' => $label, 'type' => 'text', 'tab' => 'general', 'params' => array()), $description['input']);
	// default
	if (isset($this->fieldInputSchema) && is_array($this->fieldInputSchema) && array_key_exists($name, $this->fieldInputSchema)) {
		$description['input'] = array_merge($description['input'], $this->fieldInputSchema[$name]);
	}
	if (isset($this->xFormSchema) && is_array($this->xFormSchema) && array_key_exists($name, $this->xFormSchema)) {
		$description['input'] = array_merge($description['input'], $this->xFormSchema[$name]);
	}
	$description['input'] = array_merge($description['input'], $this->_describeFieldInput($Model, $name, $description));
	// model
	if (property_exists($Model, 'fieldInputSchema') && is_array($Model->fieldInputSchema) && array_key_exists($name, $Model->fieldInputSchema)) {
		$description['input'] = array_merge($description['input'], $Model->fieldInputSchema[$name]);
	}
	if (property_exists($Model, 'xFormSchema') && is_array($Model->xFormSchema) && array_key_exists($name, $Model->xFormSchema)) {
		$description['input'] = array_merge($description['input'], $Model->xFormSchema[$name]);
	}
	if (property_exists($Model, 'formSchema') && is_array($Model->formSchema) && array_key_exists($name, $Model->formSchema)) {
		$description['input'] = array_merge($description['input'], $Model->formSchema[$name]);
	}

	if (method_exists($Model, '_describeFieldInput')) $description['input'] = array_merge($description['input'], $Model->_describeFieldInput($name, $description));
//
$spacer = '_';
	if ($fill && ($name !== 'foreign_key')) {
		if ($this->isTreeKey($Model, $name)) {
			$description['input']['type'] = 'select';
			$description['input']['class'] = 'tree';
			$description['input']['options'] = $this->generateTreeListPossible($Model, $id, NULL, NULL, NULL, $spacer);
			$description['input']['empty'] = '(' . __('root', TRUE) . ')';
		} elseif ($this->isRubricKey($Model, $name) && is_object($RubricModel = $this->getRubricModel($Model))) {
			$description['input']['type'] = 'select';
			$description['input']['class'] = 'rubric';
			$description['input']['options'] = $this->isTree($RubricModel) ? $RubricModel->generateTreeList(NULL, NULL, NULL, $spacer) : $RubricModel->find('list');
		} elseif ($this->isForeignKey($Model, $name) && is_object($ForeignModel = $this->getForeignModel($Model, $name))) {
			$description['input']['type'] = 'select';
			$description['input']['class'] = 'foreign';
			$description['input']['options'] = $this->isTree($ForeignModel) ? $ForeignModel->generateTreeList(NULL, NULL, NULL, $spacer) : $ForeignModel->find('list');
		}
	}
//
	// params
	if (is_string($description['input']['params'])) {
		parse_str($description['input']['params'], $params);
		$description['input']['params'] = is_array($params) ? $params : array();
	}
	return $description;
}

function getFieldSchema(&$Model, $fill = FALSE, $id = NULL, $row = array()) {
$spacer = '_';
	$schema = $Model->schema();
	foreach ($schema as $name => $description) {
		$schema[$name] = $this->describeField($Model, $name, $fill, $id, $row);
	}
	// habtm
	foreach ((array)$Model->hasAndBelongsToMany as $info) {
		$HabtmModel = $Model->{$info['className']}; // ???
		$description = $this->describeField($Model, $HabtmModel->name);
// label
$label = __('habtm_' . Inflector::tableize($HabtmModel->name) . '_field', TRUE);
if ((bool)preg_match('~_field$~', $label)) {
$label = __('habtm_' . Inflector::tableize($HabtmModel->name) . '_label', TRUE);
}
//
		$description['input']['label'] = $label;
		$description['input']['type'] = 'select';
		$description['input']['multiple'] = 'checkbox';
		$description['input']['class'] = 'habtm';
		$description['input']['tab'] = 'habtm';
		if ($fill) $description['input']['options'] = $this->isTree($HabtmModel) ? $HabtmModel->generateTreeList(NULL, NULL, NULL, $spacer) : $HabtmModel->find('list');
		$description['input']['between'] = '<div class="checkboxes">';
		$description['input']['after'] = '</div>';
		$schema[$HabtmModel->name] = $description;
	}
	return $schema;
}

function getFieldType(&$Model, $name) {
	$description = $this->describeField($Model, $name);
	return $description['input']['type'];
}

/******************************************************************************/

function setup(&$Model, $settings) {
	$this->settings[$Model->name] = (array)$settings;

// position
if ($Model->hasField('position')) {
	//if (isset($Model->neighborhood) && !empty($Model->neighborhood)) {
	//	$neighborhood = $Model->neighborhood;
	//} else {
		$neighborhood = array();
		if ($this->isTree($Model)) {
			$neighborhood[] = $this->getParentKey($Model);
		} elseif ($this->hasRubric($Model)) {
			$neighborhood[] = $this->getRubricKey($Model);
		}
		if ($this->isAttachment($Model)) {
			$neighborhood[] = 'model';
			$neighborhood[] = 'foreign_key';
		}
	//}
	$Model->Behaviors->attach('Routines.Sortable', array('neighborhood' => $neighborhood));
}

	// attach behaviors
	$behaviors = array('Admin.TabSchema');
	foreach ($this->getFieldSchema($Model) as $field_name => $field_description) {
		if (fileExistsInPath(ADMIN_BEHAVIORS . 'field_name_' . $field_name . '.php')) {
			$behaviors['Admin.FieldName' . Inflector::camelize($field_name)] = $field_description['input']['params'];
		}
		if (fileExistsInPath(ADMIN_BEHAVIORS . 'field_type_' . $field_description['input']['type'] . '.php')) {
			$behaviors['Admin.FieldType' . Inflector::camelize($field_description['input']['type'])][$field_name] = $field_description['input']['params'];
		}
	}
	foreach (Set::normalize($behaviors) as $behavior_name => $behavior_settings) {
		$Model->Behaviors->attach($behavior_name, $behavior_settings);
	}
}

/******************************************************************************/

function setId(&$Model, $id = NULL) {
	if (!is_null($id)) $Model->id = $id;
}

function idExists(&$Model, $id = NULL) {
	$this->setId($Model, $id); //$Model->id = $id;
	return $Model->exists();
}

/******************************************************************************/

function getField(&$Model, $name, $id = NULL) {
	if ($Model->hasField($name)) {
		$this->setId($Model, $id); //$Model->id = $id;
		return $Model->field($name);
	}
	return NULL;
}

function setField(&$Model, $name, $value, $id = NULL) {
	if ($Model->hasField($name)) {
		$this->setId($Model, $id); //$Model->id = $id;
		return $Model->saveField($name, $value, TRUE);
	}
	return FALSE;
}

function toggleField(&$Model, $name, $id = NULL) {
	return $this->setField($Model, $name, !(bool)$this->getField($Model, $name, $id), $id);
}

function toggleBooleanField(&$Model, $name, $id = NULL) {
	return $Model->hasField($name) && ($Model->getColumnType($name) === 'boolean') ? $this->toggleField($Model, $name, $id) : FALSE;
}

/******************************************************************************/

function move(&$Model, $id = NULL, $parent_id = NULL) {
	return FALSE; // dummy
}

/******************************************************************************/

function moveBefore(&$Model, $id = NULL, $parent_id = NULL, $neighbor_id = NULL) {
	return $this->move($Model, $id, $parent_id) && $this->before($Model, $id, $neighbor_id);
}

function moveAfter(&$Model, $id = NULL, $parent_id = NULL, $neighbor_id = NULL) {
	return $this->move($Model, $id, $parent_id) && $this->after($Model, $id, $neighbor_id);
}

/******************************************************************************/

function dropBefore(&$Model, $id = NULL, $neighbor_id = NULL) {
	return $this->isTree($Model) ? $this->move_before($Model, $id, $this->getParentId($Model, $neighbor_id), $neighbor_id) : $this->before($Model, $id, $neighbor_id);
}

function dropAfter(&$Model, $id = NULL, $neighbor_id = NULL) {
	return $this->isTree($Model) ? $this->move_after($Model, $id, $this->getParentId($Model, $neighbor_id), $neighbor_id) : $this->after($Model, $id, $neighbor_id);
}

/******************************************************************************/

function isPrimaryKey(&$Model, $name) {
	return ($Model->primaryKey === $name) || is_array($description = $Model->schema($name)) && array_key_exists('key', $description) && ($description['key'] === 'primary');
}

/******************************************************************************/

function isForeignKey(&$Model, $name) {
	return $Model->isForeignKey($name);
}

function hasForeign(&$Model, $foreignKey) {
	return is_array($info = $this->getForeignInfo($Model, $foreignKey)) && array_key_exists('foreignKey', $info) && $Model->hasField($info['foreignKey']);
}

function getForeignInfo(&$Model, $foreignKey) {
	foreach ((array)$Model->belongsTo as $info) {
		if (is_array($info) && array_key_exists('foreignKey', $info) && ($info['foreignKey'] === $foreignKey)) return $info;
	}
	return FALSE;
}

function getForeignModel(&$Model, $foreignKey) {
	return is_array($info = $this->getForeignInfo($Model, $foreignKey)) && array_key_exists('className', $info) && isset($Model->{$info['className']}) ? $Model->{$info['className']} : NULL;
}

function getForeignId(&$Model, $foreignKey, $id = NULL) {
	return is_array($info = $this->getForeignInfo($Model, $foreignKey)) && array_key_exists('foreignKey', $info) ? $this->getField($Model, $info['foreignKey'], $id) : NULL;
}

/******************************************************************************/

function isTreeKey(&$Model, $name) {
	return is_array($info = $this->getTreeInfo($Model)) && array_key_exists('parent', $info) && $Model->hasField($info['parent']) && ($info['parent'] === $name);
}

function isTree(&$Model) {
	return is_array($info = $this->getTreeInfo($Model)) && array_key_exists('parent', $info) && $Model->hasField($info['parent']);
}

function getTreeInfo(&$Model) {
	return $Model->Behaviors->attached('Tree') ? $Model->Behaviors->Tree->settings[$Model->name] : FALSE;
}

function getParentId(&$Model, $id = NULL) {
	return is_array($info = $this->getTreeInfo($Model)) && array_key_exists('parent', $info) ? $this->getField($Model, $info['parent'], $id) : NULL;
}

function getParentKey(&$Model) {
$info = $this->getTreeInfo($Model);
	return $info['parent'];
}

function getTree_ParentId_Lft_Rght(&$Model, $id = NULL) {
	$data = is_array($info = $this->getTreeInfo($Model)) && array_key_exists('parent', $info) && array_key_exists('left', $info) && array_key_exists('right', $info) ? $Model->read(array($info['parent'], $info['left'], $info['right']), $id) : FALSE;
	return is_array($data) && array_key_exists($Model->name, $data) ? $data[$Model->name] : FALSE;
}

function generateTreeListPossible(&$Model, $id = NULL, $conditions = NULL, $keyPath = NULL, $valuePath = NULL, $spacer = '_', $recursive = NULL) {
	if (is_array($tree_info = $this->getTreeInfo($Model))) {
		if (!empty($id) && is_array($tree_data = $this->getTree_ParentId_Lft_Rght($Model, $id))) {
			$conditions[] = array('or' => array($Model->name . '.' . $tree_info['left'] . ' <' => $tree_data[$tree_info['left']], $Model->name . '.' . $tree_info['right'] . ' >' => $tree_data[$tree_info['right']]));
		}
		return $Model->generateTreeList($conditions, $keyPath, $valuePath, $spacer, $recursive);
	}
	return FALSE;
}

function getNumChildren(&$Model, $id = NULL) {
	return 0; // dummy
}

/******************************************************************************/

function isRubricKey(&$Model, $name) {
	return is_array($info = $this->getRubricInfo($Model)) && array_key_exists('foreignKey', $info) && $Model->hasField($info['foreignKey']) && ($info['foreignKey'] === $name);
}

function hasRubric(&$Model) {
	return is_array($info = $this->getRubricInfo($Model)) && array_key_exists('foreignKey', $info) && $Model->hasField($info['foreignKey']);
}

function getRubricInfo(&$Model) {
	foreach ((array)$Model->belongsTo as $info) {
		if (is_array($info) && array_key_exists('className', $info) && ($info['className'] === $Model->name . 'Rubric')) return $info;
		if (is_array($info) && array_key_exists('is_rubric', $info) && (bool)$info['is_rubric']) return $info;
		if (is_array($info) && array_key_exists('isRubric', $info) && (bool)$info['isRubric']) return $info;
	}
	return FALSE;
}

function getRubricDescription(&$Model) {
	foreach ((array)$Model->belongsTo as $info) {
		if (is_array($info) && array_key_exists('className', $info) && ($info['className'] === $Model->name . 'Rubric')) return $info;
		if (is_array($info) && array_key_exists('is_rubric', $info) && (bool)$info['is_rubric']) return $info;
		if (is_array($info) && array_key_exists('isRubric', $info) && (bool)$info['isRubric']) return $info;
	}
	return FALSE;
}

function getRubricKey(&$Model) {
$rubric_desc = $this->getRubricDescription($Model);
	return $rubric_desc['foreignKey'];
}



function getRubricModel(&$Model) {
	return is_array($info = $this->getRubricInfo($Model)) && array_key_exists('className', $info) && isset($Model->{$info['className']}) ? $Model->{$info['className']} : NULL;
}

function getRubricId(&$Model, $id = NULL) {
	return is_array($info = $this->getRubricInfo($Model)) && array_key_exists('foreignKey', $info) ? $this->getField($Model, $info['foreignKey'], $id) : NULL;
}

/******************************************************************************/

function hasItems(&$Model) {
	return is_array($info = $this->getItemInfo($Model)) && !empty($info);
}

function getItemInfo(&$Model) {
	foreach ((array)$Model->hasMany as $info) {
		if (is_array($info) && array_key_exists('className', $info) && ($info['className'] . 'Rubric' === $Model->name)) return $info;
		if (is_array($info) && array_key_exists('is_item', $info) && (bool)$info['is_item']) return $info;
		if (is_array($info) && array_key_exists('isItem', $info) && (bool)$info['isItem']) return $info;
	}
	return FALSE;
}

function getItemModel(&$Model) {
	return is_array($info = $this->getItemInfo($Model)) && array_key_exists('className', $info) && isset($Model->{$info['className']}) ? $Model->{$info['className']} : NULL;
}

function getNumItems(&$Model, $id = NULL) {
	return 0; // dummy
}

/******************************************************************************/

function isAttachment(&$Model) {
	return $Model->hasField('model') && $Model->hasField('foreign_key');
}

function getAttachment_Model(&$Model, $id = NULL) {
	return $this->isAttachment($Model) ? $this->getField($Model, 'model', $id) : NULL;
}

function getAttachment_ForeignKey(&$Model, $id = NULL) {
	return $this->isAttachment($Model) ? $this->getField($Model, 'foreign_key', $id) : NULL;
}

function getAttachment_Model_ForeignKey(&$Model, $id = NULL) {
	$data = $this->isAttachment($Model) ? $Model->read(array('model', 'foreign_key'), $id) : FALSE;
	return is_array($data) && array_key_exists($Model->name, $data) ? $data[$Model->name] : FALSE;
}

/******************************************************************************/

function getIndexURL(&$Model, $id = NULL) {
	$url = array('controller' => Inflector::tableize($Model->name), 'action' => 'index');
	if ($this->isTree($Model)) {
		$url[] = $this->getParentId($Model, $id);
	} elseif ($this->hasRubric($Model)) {
		$url[] = $this->getRubricId($Model, $id);
	}
	if ($this->isAttachment($Model)) {
		$url = array_merge($url, (array)$this->getAttachment_Model_ForeignKey($Model, $id));
	}
	return $url;
}

function getIndexPageURL(&$Model, $id = NULL) {
	$url = array('controller' => Inflector::tableize($Model->name), 'action' => 'index');
	if ($this->isTree($Model)) {
		$url[] = $this->getParentId($Model, $id);
	} elseif ($this->hasRubric($Model)) {
		$url[] = $this->getRubricId($Model, $id);
	}
	if ($this->isAttachment($Model)) {
		$url = array_merge($url, (array)$this->getAttachment_Model_ForeignKey($Model, $id));
	}
	$url['autoPage'] = TRUE;
	return $url;
}

function getViewURL(&$Model, $id = NULL) {
	$url = array('controller' => Inflector::tableize($Model->name), 'action' => 'view', 'id' => $id);
	if ($this->isAttachment($Model)) $url = array_merge($url, (array)$this->getAttachment_Model_ForeignKey($Model, $id));
	return $url;
}

/******************************************************************************/

function scopeConditions(&$Model) {
	$conditions = (bool)Configure::read('admin') ? array() : $Model->scopeConditions;
	if (!(bool)Configure::read('admin') && !(bool)Configure::read('preview')) {
		if ($Model->hasField('hidden')) $conditions[$Model->name . '.hidden'] = FALSE;
		if ($Model->hasField('disabled')) $conditions[$Model->name . '.disabled'] = FALSE;
	}
	if ($Model->hasField('deleted')) $conditions[$Model->name . '.deleted'] = FALSE;
	return $conditions;
}

function buildContain(&$Model, $level = 3) {
	$contain = array();
	if ($level >= 1) foreach ((array)$Model->belongsTo as $submodel => $info) {
		if (property_exists($Model, $submodel)) {
			$contain[$submodel]['conditions'] = array_merge((array)$info['conditions'], $Model->{$submodel}->scopeConditions());
			if (isset($info['order']) && !empty($info['order'])) {
				$contain[$submodel]['order'] = $info['order'];
			} else {
				$contain[$submodel]['order'] = $Model->{$submodel}->order;
			}
		}
	}
	if ($level >= 2) foreach ((array)$Model->hasMany as $submodel => $info) {
		if (property_exists($Model, $submodel)) {
			$contain[$submodel]['conditions'] = array_merge((array)$info['conditions'], $Model->{$submodel}->scopeConditions());
			if (isset($info['order']) && !empty($info['order'])) {
				$contain[$submodel]['order'] = $info['order'];
			} else {
				$contain[$submodel]['order'] = $Model->{$submodel}->order;
			}
		}
	}
	if ($level >= 3) foreach ((array)$Model->hasAndBelongsToMany as $submodel => $info) {
		if (property_exists($Model, $submodel)) {
			$contain[$submodel]['conditions'] = array_merge((array)$info['conditions'], $Model->{$submodel}->scopeConditions());
			if (isset($info['order']) && !empty($info['order'])) {
				$contain[$submodel]['order'] = $info['order'];
			} else {
				$contain[$submodel]['order'] = $Model->{$submodel}->order;
			}
		}
	}
	return $contain;
}

/******************************************************************************/

function beforeFind(&$Model, $query) {
	$query['conditions'] = array_merge($this->scopeConditions($Model), (array)$query['conditions']);
///	if (!isset($query['contain'])) $query['contain'] = $this->buildContain($Model, 1);
	return $query;
}

function afterFind(&$Model, $results, $primary) {
	if (is_array($results)) {
		foreach ($results as $i => $result) {
			if (array_key_exists($Model->name, $result) && is_array($model_data = $result[$Model->name])) {
//
//
			}
		}
	}
	return $results;
}

/******************************************************************************/

function afterSave(&$Model, $created) {
	Cache::clear();
}

function afterDelete(&$Model) {
	Cache::clear();
}

/******************************************************************************/

}


?>